package com.aaa.forum.controller;

import com.aaa.forum.common.AppResult;
import com.aaa.forum.common.ResultCode;
import com.aaa.forum.config.AppConfig;
import com.aaa.forum.model.*;
import com.aaa.forum.services.*;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import java.util.List;
import java.util.Objects;

@Api(tags = "帖子接口")
@Slf4j
@RestController
@RequestMapping("/article")
public class ArticleController {
    @Resource
    private IArticleService articleService;

    @Resource
    private IBoardService boardService;

    @Resource
    private IArticleLikeService articleLikeService;

    @Resource
    private IBookmarkService bookmarkService;

    @Resource
    private ISubscribeService subscribeService;

    @Resource
    private IUserSettingService userSettingService;

    @Resource
    private IUserService userService;

    @Resource
    private IMessageService messageService;

    @ApiOperation("发布新帖子")
    @PostMapping("/create")
    public AppResult create(HttpServletRequest request,
                            @ApiParam("板块id") @RequestParam("boardId") Long boardId,
                            @ApiParam("标题") @RequestParam("title") String title,
                            @ApiParam("正文") @RequestParam("content") String content) {
        // 校验用户是否被禁言
        HttpSession session = request.getSession(false);
        User user = (User) session.getAttribute(AppConfig.USER_SESSION);
        if (user.getState() == 1) {
            log.warn(ResultCode.FAILED_USER_BANNED.toString());
            return AppResult.failed(ResultCode.FAILED_USER_BANNED);
        }

        // 校验板块
        Board board = boardService.selectById(boardId);
        if (board == null || board.getDeleteState() == 1) {
            log.warn(ResultCode.FAILED_BOARD_NOT_EXISTS.toString());
            // 如果查询不到板块, 或者该板块已被删除
            return AppResult.failed(ResultCode.FAILED_BOARD_NOT_EXISTS);
        }
        if (board.getState() == 1) {
            // 该板块被禁言
            log.warn(ResultCode.FAILED_BOARD_BANNED.toString());
            return AppResult.failed(ResultCode.FAILED_BOARD_BANNED);
        }

        // 构造文章对象
        Article article = new Article();
        article.setTitle(title);        // 标题
        article.setContent(content);    // 正文
        article.setBoardId(boardId);    // 板块id
        article.setUserId(user.getId());// 作者id

        // 调用service
        articleService.create(article);

        user.setArticleCount(user.getArticleCount() + 1);
        session.setAttribute(AppConfig.USER_SESSION, user);

        return AppResult.success(ResultCode.SUCCESS);
    }

    @ApiOperation("根据板块id获取帖子列表")
    @GetMapping("/getListByBoardId")
    public AppResult<List<Article>> getListByBoardId(@ApiParam("板块id") @RequestParam(value = "boardId", required = false) Long boardId) {
        // 定义返回集合
        List<Article> articles;

        if (boardId == null) {
            // boardId 为空, 查询所有的帖子
            articles = articleService.selectAll();
        } else {
            // boardId 不为空, 查询对应板块下的所有帖子
            articles = articleService.selectAllByBoardId(boardId);
        }
        return AppResult.success(articles);
    }

    @ApiOperation("根据帖子id获取帖子详情")
    @GetMapping("/getDetail")
    public AppResult<Article> getDetail(HttpServletRequest request,
                                        @ApiParam("帖子id") @RequestParam("id") Long id) {
        HttpSession session = request.getSession(false);
        User user = (User) session.getAttribute(AppConfig.USER_SESSION);
        // 获取帖子详情
        Article article = articleService.selectDetailById(user.getId(), id);

        // 获取当前用户对该贴的点赞状态
        Byte likeState = articleLikeService.getState(user.getId(), article.getId());
        // 获取当前用户对该贴的收藏状态
        Byte markState = bookmarkService.getState(user.getId(), article.getId());
        // 获取当前用户对该作者的关注状态
        Byte subscribeState = subscribeService.getState(user.getId(), article.getUser().getId());

        article.setLikeState(likeState);
        article.setMarkState(markState);
        article.getUser().setSubscribeState(subscribeState);

        return AppResult.success(article);
    }

    @ApiOperation("编辑帖子")
    @PostMapping("/modify")
    public AppResult modify(HttpServletRequest request,
                            @ApiParam("帖子id") @RequestParam("id") Long id,
                            @ApiParam("帖子标题") @RequestParam("title") String title,
                            @ApiParam("帖子正文") @RequestParam("content") String content,
                            @ApiParam("板块id") @RequestParam("boardId") Long boardId) {
        // 1. 校验是否被禁言
        HttpSession session = request.getSession(false);
        User user = (User) session.getAttribute(AppConfig.USER_SESSION);
        if (user.getState() == 1) {
            // 禁言状态
            log.warn(ResultCode.FAILED_USER_BANNED.toString());
            return AppResult.failed(ResultCode.FAILED_USER_BANNED);
        }
        // 2. 校验该帖子是否存在
        Article article = articleService.selectById(id);
        if (article == null || article.getDeleteState() == 1) {
            log.warn(ResultCode.FAILED_ARTICLE_NOT_EXISTS.toString());
            return AppResult.failed(ResultCode.FAILED_ARTICLE_NOT_EXISTS);
        }
        // 3. 校验用户权限（该帖子是否属于该用户）
        if (user.getId() != article.getUserId()) {
            log.warn(ResultCode.FAILED_FORBIDDEN.toString());
            return AppResult.failed(ResultCode.FAILED_FORBIDDEN);
        }
        // 4. 校验板块是否存在
        Board board = boardService.selectById(boardId);
        if (board == null || board.getDeleteState() == 1) {
            log.warn(ResultCode.FAILED_BOARD_NOT_EXISTS.toString());
            return AppResult.failed(ResultCode.FAILED_BOARD_NOT_EXISTS);
        }
        // 5. 板块状态
        if (board.getState() != 0) {
            log.warn(ResultCode.FAILED_BOARD_BANNED.toString());
            return AppResult.failed(ResultCode.FAILED_BOARD_BANNED);
        }

        // 校验通过, 更新数据库
        articleService.modify(id, title, content, boardId);
        return AppResult.success(ResultCode.SUCCESS);
    }

    @ApiOperation("删除帖子")
    @PostMapping("/delete")
    public AppResult deleteById(HttpServletRequest request,
                                @ApiParam("帖子id") @RequestParam("id") Long id) {
        // 1. 校验用户状态
        HttpSession session = request.getSession(false);
        User user = (User) session.getAttribute(AppConfig.USER_SESSION);
        if (user.getState() == 1) {
            log.warn(ResultCode.FAILED_USER_BANNED.toString());
            return AppResult.failed(ResultCode.FAILED_USER_BANNED);
        }

        // 2. 查询帖子信息, 校验帖子状态
        Article article = articleService.selectById(id);
        if (article == null || article.getDeleteState() == 1) {
            log.warn(ResultCode.FAILED_ARTICLE_NOT_EXISTS.toString());
            return AppResult.failed(ResultCode.FAILED_ARTICLE_NOT_EXISTS);
        }

        // 3. 校验当前用户是否为帖子作者
        if (user.getId() != article.getUserId()) {
            log.warn(ResultCode.FAILED_FORBIDDEN.toString());
            return AppResult.failed(ResultCode.FAILED_FORBIDDEN);
        }

        // 4. 调用Service
        articleService.deleteById(id);
        return AppResult.success(ResultCode.SUCCESS);
    }

    @ApiOperation("查询用户的帖子列表")
    @GetMapping("/getAllByUserId")
    public AppResult getAllByUserId(HttpServletRequest request,
                                    @ApiParam("用户id") @RequestParam(value = "userId",required = false) Long userId) {
        if (userId == null) {
            HttpSession session = request.getSession(false);
            userId = ((User)session.getAttribute(AppConfig.USER_SESSION)).getId();
        }
        return AppResult.success(articleService.selectAllByUserId(userId));
    }


    @ApiOperation("查询当前登录用户所关注的人的帖子")
    @GetMapping("/getBySubscribe")
    public AppResult getBySubscribe(HttpServletRequest request) {
        HttpSession session = request.getSession(false);
        User user = (User) session.getAttribute(AppConfig.USER_SESSION);
        return AppResult.success(articleService.selectBySubscribe(user.getId()));
    }


    @ApiOperation("查询默认收藏夹的帖子列表")
    @GetMapping("/getByDefaultCollection")
    public AppResult getByDefaultCollection(HttpServletRequest request,
                                            @ApiParam("用户id") @RequestParam(value = "userId",required = false) Long userId) {
        HttpSession session = request.getSession(false);
        User user = (User) session.getAttribute(AppConfig.USER_SESSION);

        if (userId == null || userId == user.getId()) {
            return AppResult.success(articleService.selectByDefaultCollection(user.getId()));
        }

        // 校验用户是否存在
        User existsUser = userService.selectById(userId);
        if (existsUser == null || existsUser.getDeleteState() == 1) {
            log.warn(ResultCode.FAILED_USER_NOT_EXISTS.toString());
            return AppResult.failed(ResultCode.FAILED_USER_NOT_EXISTS);
        }
        UserSetting userSetting = userSettingService.selectByUserId(userId);
        if (userSetting.getCollectionState() == 1) {
            log.warn(ResultCode.FAILED_FORBIDDEN.toString());
            return AppResult.failed(ResultCode.FAILED_FORBIDDEN);
        }

        return AppResult.success(articleService.selectByDefaultCollection(userId));
    }

    @ApiOperation("根据收藏夹id查询帖子列表")
    @GetMapping("/getByCollectionId")
    public AppResult getByCollectionId(@ApiParam("收藏夹id") @RequestParam("collectionId") Long collectionId) {
        // TODO: 2024/3/6 后续如果有需要，再实现获取他人的收藏夹信息，以及收藏夹权限校验
        return AppResult.success(articleService.selectByCollectionId(collectionId));
    }

    @ApiOperation("根据标题查询帖子列表")
    @GetMapping("/getListByTitle")
    public AppResult getListByTitle(@ApiParam("帖子标题") @RequestParam("title") String title) {
        return AppResult.success(articleService.selectByTitle(title));
    }

    @ApiOperation("获取审核状态下的帖子")
    @GetMapping("/getExamineList")
    public AppResult<List<Article>> getExamineList(HttpServletRequest request,
                                                   @ApiParam("是否获取全部") @RequestParam(value = "getAll", required = false) Boolean getAll) {
        List<Article> articles = null;
        HttpSession session = request.getSession(false);
        User user = (User) session.getAttribute(AppConfig.USER_SESSION);

        if (getAll != null && getAll && user.getIsAdmin() == 1) {
            // 管理员，获取全部 审核中 的帖子
            articles = articleService.selectAllExamine();
        } else {
            // 不是管理员，获取自己审核状态下的帖子
            articles = articleService.selectAllExamineByUserId(user.getId());
        }
        return AppResult.success(articles);
    }

    @ApiOperation("根据帖子id，获取任意状态的帖子详情，并且不更新访问数量")
    @GetMapping("/getAllState")
    public AppResult<Article> getAllState(HttpServletRequest request,
                                                @ApiParam("帖子id") @RequestParam("id") Long id) {
        Article article = articleService.selectAllState(id);
        if (article == null || article.getDeleteState() == 1) {
            return AppResult.failed(ResultCode.FAILED_ARTICLE_NOT_EXISTS);
        }

        HttpSession session = request.getSession(false);
        User user = (User) session.getAttribute(AppConfig.USER_SESSION);

        if (article.getState() != 0 && !Objects.equals(user.getId(), article.getUserId()) && user.getIsAdmin() != 1) {
            // 帖子处于审核状态，只有作者和管理员可以获取
            return AppResult.failed(ResultCode.FAILED_FORBIDDEN);
        }
        return AppResult.success(article);
    }


    @ApiOperation("通过审核")
    @PostMapping("/pass")
    public AppResult pass(HttpServletRequest request,
                          @ApiParam("帖子id") @RequestParam("id") Long id) {
        HttpSession session = request.getSession(false);
        User user = (User) session.getAttribute(AppConfig.USER_SESSION);
        // 1. 校验用户权限
        if (user.getIsAdmin() != 1) {
            // 只有管理员可以操作
            return AppResult.failed(ResultCode.FAILED_FORBIDDEN);
        }
        // 2. 校验帖子是否存在
        Article article = articleService.selectById(id);
        if (article == null || article.getDeleteState() == 1) {
            return AppResult.failed(ResultCode.FAILED_ARTICLE_NOT_EXISTS);
        }
        // 3. 校验帖子状态
        if (article.getState() != 1) {
            // 只有审核中的帖子可以通过审核
            return AppResult.failed(ResultCode.FAILED_ARTICLE_BANNED);
        }
        // 4. 调用service，更新帖子状态
        articleService.modifyState(id, (byte) 0);
        return AppResult.success();
    }

    @ApiOperation("不通过审核")
    @PostMapping("/fail")
    public AppResult fail(HttpServletRequest request,
                          @ApiParam("帖子id") @RequestParam("id") Long id,
                          @ApiParam("理由") @RequestParam("reason") String reason) {
        HttpSession session = request.getSession(false);
        User user = (User) session.getAttribute(AppConfig.USER_SESSION);
        // 1. 校验用户权限
        if (user.getIsAdmin() != 1) {
            // 只有管理员可以操作
            return AppResult.failed(ResultCode.FAILED_FORBIDDEN);
        }
        // 2. 校验帖子是否存在
        Article article = articleService.selectById(id);
        if (article == null || article.getDeleteState() == 1) {
            return AppResult.failed(ResultCode.FAILED_ARTICLE_NOT_EXISTS);
        }
        // 3. 校验帖子状态
        if (article.getState() != 1) {
            // 只能操作审核中的帖子
            return AppResult.failed(ResultCode.FAILED_ARTICLE_BANNED);
        }
        // 4. 调用service，更新帖子状态
        articleService.modifyState(id, (byte) 2);
        // 5. 给用户发送系统消息
        Message message = new Message();
        message.setPostUserId(0L);
        message.setReceiveUserId(article.getUserId());
        message.setContent("【审核不通过】 " + "您的帖子 " + '”' + article.getTitle() + '"' + " 没有通过审核，理由是：" + '“' + reason + '”' + '。');
        messageService.create(message);
        // 6. 返回结果
        return AppResult.success();
    }
}
